package com.tbynet.jwp.service.spi;

import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Page;
import com.tbynet.jwp.model.Users;
import com.tbynet.jwp.model.Usermeta;

import java.util.*;

/**
 * 用户管理编排层
 *
 * 核心职责：
 * 1. 用户生命周期管理（注册、登录、更新、删除）
 * 2. 会话管理和权限控制
 * 3. 用户信息管理和查询
 * 4. 用户统计和通知
 *
 * 设计原则：
 * - 不包含任何SQL代码，只编排Service层方法
 * - 一个方法完成一个完整的业务用例
 * - 统一的事务管理和错误处理
 * - 支持性能监控和统计
 *
 * @author 佰亿互联
 * @version 3.1
 * @since 2025-11-04
 */
public interface UserManager {

    // ============ 用户认证和会话管理 ============

    /**
     * 用户登录业务编排
     *
     * @param username 用户名或邮箱地址（必需）
     * @param password 用户密码（明文，必需）
     * @param keepLogin 是否保持登录状态（可选，默认false）
     * @param loginIp 用户登录IP地址（必需）
     * @param userAgent 用户浏览器代理信息（可选）
     * @return Ret 登录结果，包含会话信息和用户数据
     *         - 成功：包含sessionId、userInfo、maxAgeInSeconds
     *         - 失败：包含错误码和错误消息
     *
     * @example
     * <pre>{@code
     * Ret result = userManager.login("admin", "password123", true, "192.168.1.1", "Mozilla/5.0");
     * if (result.isOk()) {
     *     String sessionId = result.getStr(Users.sessionIdName);
     *     Users user = result.get(Users.loginUserCacheName);
     *     // 处理登录成功逻辑
     * } else {
     *     String errorMsg = result.getStr("msg");
     *     // 处理登录失败逻辑
     * }
     * }</pre>
     */
    Ret login(final String username, final String password, final Boolean keepLogin,
                     final String loginIp, final String userAgent);

    /**
     * 用户登出业务编排
     *
     * @param sessionId 用户会话ID（必需）
     * @return Ret 登出结果
     *         - 成功：包含成功消息
     *         - 失败：包含错误信息
     *
     * @example
     * <pre>{@code
     * Ret result = userManager.logout("session-id-123");
     * if (result.isOk()) {
     *     System.out.println("登出成功");
     * }
     * }</pre>
     */
    Ret logout(final String sessionId);

    /**
     * 用户注册业务编排
     *
     * @param username 用户名（必需）
     * @param password 密码（明文，必需）
     * @param email 邮箱（必需）
     * @param nickname 昵称（可选）
     * @param registerIp 注册IP（必需）
     * @param userAgent 用户代理（可选）
     * @return Ret 注册结果
     *         - 成功：包含用户ID
     *         - 失败：包含错误码和错误消息
     *
     * @example
     * <pre>{@code
     * Ret result = userManager.register("newuser", "password123",
     *     "user@example.com", "昵称", "192.168.1.1", "Mozilla/5.0");
     * if (result.isOk()) {
     *     Long userId = result.getAs("data");
     *     // 处理注册成功逻辑
     * }
     * }</pre>
     */
    Ret register(final String username, final String password, final String email,
                        final String nickname, final String registerIp, final String userAgent);

    // ============ 用户信息管理 ============

    /**
     * 创建用户业务编排
     *
     * @param user 用户基本信息（必需）
     * @param metas 用户元数据列表（可选）
     * @return Ret 创建结果
     *         - 成功：包含用户ID
     *         - 失败：包含错误信息
     *
     * @example
     * <pre>{@code
     * Users user = new Users();
     * user.setUserLogin("testuser");
     * user.setUserEmail("test@example.com");
     *
     * List<Usermeta> metas = new ArrayList<>();
     * metas.add(new Usermeta().setMetaKey("key").setMetaValue("value"));
     *
     * Ret result = userManager.createUser(user, metas);
     * if (result.isOk()) {
     *     Long userId = result.getAs("data");
     * }
     * }</pre>
     */
    Ret createUser(final Users user, final List<Usermeta> metas);

    /**
     * 更新用户信息业务编排
     *
     * @param user 更新后的用户信息（必需）
     * @param metas 更新后的元数据列表（可选）
     * @return Ret 更新结果
     *         - 成功：包含用户ID
     *         - 失败：包含错误信息
     *
     * @example
     * <pre>{@code
     * Users user = userManager.getUserDetail(1L);
     * user.setDisplayName("新显示名称");
     *
     * Ret result = userManager.updateUser(user, null);
     * if (result.isOk()) {
     *     System.out.println("更新成功");
     * }
     * }</pre>
     */
    Ret updateUser(final Users user, final List<Usermeta> metas);

    /**
     * 删除用户业务编排
     *
     * @param userId 用户ID（必需）
     * @return Ret 删除结果
     *         - 成功：包含成功消息
     *         - 失败：包含错误信息
     *
     * @example
     * <pre>{@code
     * Ret result = userManager.deleteUser(1L);
     * if (result.isOk()) {
     *     System.out.println("删除成功");
     * }
     * }</pre>
     */
    Ret deleteUser(final Object userId);

    // ============ 用户查询和搜索 ============

    /**
     * 搜索用户业务编排
     *
     * @param pageNumber 页码（必需）
     * @param pageSize 每页大小（必需）
     * @param keyword 搜索关键词（可选）
     * @return Page<Users> 搜索结果分页对象
     *
     * @example
     * <pre>{@code
     * Page<Users> result = userManager.searchUsers(1, 20, "admin");
     * List<Users> users = result.getList();
     * long total = result.getTotalRow();
     * }</pre>
     */
    Page<Users> searchUsers(final int pageNumber, final int pageSize, final String keyword);

    /**
     * 获取用户详情业务编排（带缓存）
     *
     * @param userId 用户ID（必需）
     * @return Users 用户详情对象，如果不存在返回null
     *
     * @example
     * <pre>{@code
     * Users user = userManager.getUserDetail(1L);
     * if (user != null) {
     *     String email = user.getUserEmail();
     *     String name = user.getDisplayName();
     * }
     * }</pre>
     */
    Users getUserDetail(final Object userId);

    // ============ 会话和权限管理 ============

    /**
     * 用户会话验证业务编排
     *
     * @param sessionId 会话ID（必需）
     * @return Users 有效的用户对象，无效返回null
     *
     * @example
     * <pre>{@code
     * Users user = userManager.validateAndGetLoginUser("session-id-123");
     * if (user != null) {
     *     // 用户已登录且会话有效
     * } else {
     *     // 会话无效或已过期
     * }
     * }</pre>
     */
    Users validateAndGetLoginUser(final String sessionId);

    /**
     * 强制登出其他设备业务编排
     *
     * @param currentSessionId 当前会话ID（必需）
     * @return Ret 操作结果
     *         - 成功：包含成功消息
     *         - 失败：包含错误信息
     *
     * @example
     * <pre>{@code
     * Ret result = userManager.destroyOtherSessions("current-session-id");
     * if (result.isOk()) {
     *     System.out.println("其他设备已登出");
     * }
     * }</pre>
     */
    Ret destroyOtherSessions(final String currentSessionId);

    /**
     * 获取用户角色权限列表
     *
     * @param role 角色名称（必需）
     * @return List<String> 权限名称列表，如果角色不存在返回空列表
     *
     * @example
     * <pre>{@code
     * List<String> permissions = userManager.getUserPermissions("administrator");
     * if (permissions.contains("manage_users")) {
     *     // 用户有管理用户的权限
     * }
     * }</pre>
     */
    List<String> getUserPermissions(final String role);
}